home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 July / Macworld (1999-07).dmg / Shareware World / Info / For Developers / Mops 3.4.sea / Mops source / PPC source / zArgs < prev    next >
Text File  |  1998-12-18  |  11KB  |  455 lines

  1. \ zArgs - support for named parms and local variables
  2.  
  3.  
  4. (*    This file is the PPC equivalent of the 68k "Args" file.  It's a
  5.     "z" file - it's not target compiled, but is loaded on the PPC itself.
  6.     Args has EVALUATE - the PPC EVALUATE has already been target compiled
  7.     in pArgs since we needed it earlier.  Here we include everything else.
  8. *)
  9.  
  10.  
  11.     11    constant    MAXPL        \ We can only spare 11 regs on PPC,
  12.                                    \  or 10 if we use I (r21).
  13.        15    constant    MAXFPL
  14.        15    constant    MAXVL
  15.  
  16. false    value        LOCFLG        \ true = looking for local var tokens
  17.     0    value        LOC_ADDR
  18. false    value        storing?
  19.  
  20. create    PARMLIST    maxPL cells 8 +  reserve
  21. create    PARMFLAGS    maxPL reserve
  22. create    FPARMLIST    maxFPL cells 8 +  reserve
  23. create    FPARMFLAGS    maxFPL  reserve
  24.  
  25.  
  26.     0    value    svhash
  27. false    value    float?
  28.     0    value    PLentry_addr
  29.  
  30.  
  31. : INITLOCS        \ Initializes flags etc.
  32.     0 -> #PL  0 -> #P  0 -> #FPL  0 -> #FP
  33.     0 -> FltFlg  false -> locFlg
  34. ;
  35.  
  36. : undef_check  ( parmflags #P i parmlist -- index )
  37.     - 4/ dup >r
  38.     tuck <  localSect? not and
  39.     IF    +
  40.         storing?
  41.         IF        1 swap c!
  42.         ELSE    c@  NIF  112 die  THEN
  43.         THEN
  44.     ELSE  2drop
  45.     THEN
  46.     r>
  47. ;
  48.  
  49.  
  50. : FINDINPARMLIST        \ ( addr -- loc# T  OR  -- F )
  51.             \ loc# counts from right to left in the local/parm list.
  52.     dup 1+ c@   & %  =  -> float?
  53.     hash -> svHash  false
  54.  
  55.     float?
  56.     IF        #FPL  0EXIT  fparmlist  #FPL
  57.     ELSE    #PL   0EXIT  parmlist   #PL
  58.     THEN
  59.     4*  bounds
  60.     DO
  61.         svHash  i @ =
  62.         IF  ( found )
  63.             drop  
  64.             float?
  65.             IF
  66.                 #FPL 
  67.                 fparmflags #FP i fparmlist  undef_check
  68.             ELSE
  69.                 #PL
  70.                 parmflags #P i parmlist  undef_check
  71.             THEN
  72.             -  1-  true  LEAVE
  73.         THEN
  74.     4 +LOOP
  75. ;
  76.  
  77.  
  78. : ADDTOPARMLIST        \ ( addr -- )  Adds an element to parmList.
  79.                     \  addr points to a counted string.
  80.  
  81.     findinParmList  ?error 95        \ Name not unique
  82.     #PL  maxPL  >  ?error 110        \ too many parms/locals
  83.     svHash
  84.     float?
  85.     IF    #FPL 1 ++> #FPL 4*  fParmlist +  !
  86.         locFlg NIF  1 ++> #FP  THEN
  87.     ELSE
  88.         #PL  tuck 1 ++> #PL  4*  parmlist  +  !
  89.         parmflags +  0 swap c!
  90.         locFlg NIF  1 ++> #P  THEN
  91.     THEN
  92. ;
  93.  
  94.  
  95. : FIRSTCHR  ( -- c )        \ assumes CDP is aligned - which should
  96.                             \  always be the case here.
  97.     inline{ CDP 1+ c@}  ;
  98.  
  99.  
  100. : gobble_to_}
  101.     BEGIN
  102.         firstChr  & }  <>
  103.     WHILE
  104.         Mword drop
  105.     REPEAT
  106. ;
  107.  
  108.  
  109. :f {
  110.     local? IF            \ local? already non-zero - this ought to mean we're
  111.                         \  in a local section
  112.         local? 0< ?error 92  -1 -> local?
  113.     THEN
  114.     initLocs
  115.  
  116.     BEGIN                    \ Loop to add parms/locals to parmlist
  117.         Mword drop
  118.         firstChr  & -  <>            \ look for --
  119.     WHILE
  120.         firstChr dup  & \  =  swap  & /  =  or
  121.                 \ Note: we allow / as an alternative to \ in this context,
  122.                 \  since it's an easy mistake to make, and / isn't a
  123.                 \  sensible parm name since it already has a meaning!
  124.  
  125.         IF        true -> locFlg
  126.         ELSE    firstChr  & } =  ?error 111
  127.                 CDP  addToParmList
  128.         THEN
  129.     REPEAT
  130.  
  131.     local? NIF                \ In local sections, we do this at :LOC
  132.         CDP  -> PLentry_addr
  133.             \  If we have temp objects, we'll have to backup the DP and
  134.             \  recompile the entry sequence, since there'll be an extra local
  135.             \  (the frame pointer)
  136.         PLentry
  137.     THEN
  138.  
  139. (*    Finally we gobble input until }.  But if we're in a :ENTRY,
  140.     we also need to check if a % comes first, as that's the way 
  141.     we declare a floating result.  If we don't get a %, we assume 
  142.     an integer result.
  143. *)
  144.     entry?
  145.     IF
  146.         Mword drop  firstChr  & % =
  147.         IF
  148.             0 -> gpr_rtn_cnt  1 -> fpr_rtn_cnt
  149.         ELSE
  150.             0 -> fpr_rtn_cnt
  151.             firstChr & } <>  negate  -> gpr_rtn_cnt
  152.         THEN
  153.     THEN
  154.  
  155.     gobble_to_}
  156. ;f
  157.  
  158.  
  159. \ FIND will call the forward-defined initFind first, to attempt to find
  160. \  a name.  At this stage in building the system we need to look for
  161. \  named parms & locals, so we define a word pFind which looks for them,
  162. \  and resolve initFind to pFind.  Later we'll re-resolve initFind to look
  163. \  for selectors, etc. as well as calling pFind.
  164.  
  165. \  If pFind finds the name is a parm/local, it returns true and the
  166. \  cfa of LocParm, which is a dummy word whose handler compiles
  167. \  a local reference.
  168.  
  169. : PFIND        \ ( str-addr -- cfa T  |  -- str-addr F )
  170.     state        NIF  false  EXIT  THEN
  171.     #PL #FPL or    NIF  false  EXIT  THEN
  172.  
  173.     dup  findInParmList  NIF  false  EXIT  THEN
  174.     
  175. \ found it!
  176.  
  177.     -> loc#  drop
  178.     float? IF  <'> FlocParm  ELSE  <'> locParm  THEN
  179.     true
  180. ;
  181.  
  182. :f initFind  pFind  ;f
  183.  
  184.  
  185. : ,EXEC        \ ( cfa n -- )
  186.     state
  187.     IF  (compN)  ELSE  exN  THEN  ;
  188.  
  189. \ Here are the different types that we can put prefixes on or send
  190. \ messages to:
  191.  
  192. enum{    notfnd  locTyp  flocTyp
  193.         tmpObjTyp  objTyp  ivarTyp  classTyp  superTyp
  194.         valTyp  fvalTyp  vecTyp  dynVecTyp  objptrTyp
  195.         regTyp  lbTyp  lbSelfTyp  bktTyp  wordTyp  }
  196.  
  197.  
  198. (*    notFnd    - not previously defined
  199.     locTyp    - a local or named parm
  200.     tmpObjTyp    - a temporary (local) object
  201.     objTyp    - an object
  202.     ivarTyp    - an ivar
  203.     classTyp    - a class
  204.     superTyp    - a named superclass specified by  msg: super> someClass
  205.     valTyp    - a value
  206.     FvalTyp    - a floating point value
  207.     vecTyp    - a vector
  208.     dynVecTyp    - a dynamic vector
  209.     regTyp    - a 680x0 register
  210.     lbTyp        - ** or [] meaning late bind
  211.     lbSelfTyp    - [self] meaning late bind to self
  212.     BktTyp    - [ - Neon-compatible late bind
  213.     wordTyp    - a word
  214. *)
  215.  
  216. : HDLR    ( xt - handler_code )
  217.     inline{ 2- w@}  ;
  218.  
  219. \ PRFTOKEN returns the type of a token for a prefix op.
  220.  
  221. : PRFTOKEN    \ ( -- cfa type )
  222.  
  223.     '  dup  <'> locParm  =  IF  locTyp    EXIT  THEN
  224.        dup  <'> FlocParm =  IF  FlocTyp    EXIT  THEN
  225.     dup  hdlr
  226.     CASE
  227.         $ BC03        OF    valTyp        ENDOF
  228.         $ BC27        OF    FvalTyp        ENDOF
  229.         $ BC05        OF    vecTyp        ENDOF
  230.         $ BC3D        OF    vecTyp        ENDOF    \ sVect
  231.         $ BC3B        OF    dynVecTyp    ENDOF
  232.         $ BD0A        OF    regTyp        ENDOF
  233.         $ BC1F        OF    objPtrTyp    ENDOF
  234.         114 die
  235.     ENDCASE  ;
  236.  
  237. forward    ToObjPtr        \ Stores to an objPtr.  Defined in file Class.
  238.  
  239. : ->
  240.     true -> storing?
  241.     prfToken                \ All types are legal
  242.     false -> storing?
  243.     objPtrTyp =  IF  toObjPtr  EXIT  THEN
  244.     $ 60  ( opcode for Store )  ,exec
  245. ;        immediate            \ NOTE: opcode for store hard coded here!!!
  246.  
  247.  
  248. : CvrtFcode    \ ( code -- code' )
  249.     CASE
  250.         $ 21  OF  $ 41  ENDOF        \ +
  251.         $ 22  OF  $ 48  ENDOF        \ -
  252.         $ 28  OF  $ 55  ENDOF        \ Neg
  253.         ?error 114
  254.     ENDCASE  ;
  255.  
  256. : (+->)        \ ( code -- cfa code' )
  257.     PrfToken ( code cfa type )  rot swap ( cfa code type )
  258.     
  259.     CASE
  260.         locTyp        OF                ENDOF
  261.         FlocTyp        OF  cvrtFcode    ENDOF
  262.         valTyp        OF                ENDOF
  263.         FvalTyp        OF  cvrtFcode    ENDOF
  264.         regTyp        OF                ENDOF
  265.         ?error 114
  266.     ENDCASE  ;
  267.  
  268. : (FOP)
  269.     PrfToken  rot swap
  270.     CASE
  271.         locTyp        OF  ENDOF
  272.         FlocTyp        OF  ENDOF
  273.         FvalTyp        OF  ENDOF
  274.         ?error 114
  275.     ENDCASE  ;
  276.  
  277.  
  278. \ Note: the following opcodes have to agree with the definitions in
  279. \ OD.asm.  I could have defined them as constants but this would have
  280. \ used up dictionary space for no great benefit.
  281.  
  282. : ++>    $ 21  (+->)  ,exec  ;        immediate
  283. : +>    postpone  ++>       ;        immediate        \ A synonym.
  284. : -->    $ 22  (+->)  ,exec  ;        immediate
  285. : AND>    $ 23  (+->)  ,exec  ;        immediate
  286. : OR>    $ 24  (+->)  ,exec  ;        immediate
  287. : XOR>    $ 25  (+->)  ,exec  ;        immediate
  288. : NEG>    $ 28  (+->)  ,exec  ;        immediate
  289. : NOT>    $ 29  (+->)  ,exec  ;        immediate
  290. : *>    $ 42  (fop)  ,exec  ;        immediate
  291. : />    $ 49  (fop)  ,exec  ;        immediate
  292. : ABS>    $ 54  (fop)  ,exec  ;        immediate
  293.  
  294.  
  295. \ ' Pfind  -> Ufind
  296.  
  297. \         =========== Local sections ===========
  298.  
  299.  
  300. forward        INITTEMPS
  301.  
  302. : ?LOC    local? 0=  ?error 91  ;            \ "We're not in a local section"
  303.  
  304.  
  305. : LOCAL
  306.     local?  ?error 93  1 -> local?        \ We change it to the normal -1
  307.                                         \ as soon as "{" is read.
  308.     true -> localSect?
  309.     CDP -> CD_gpr_loc
  310.     forward                                \ LOCAL is just like FORWARD
  311.     CDP 4- -> loc_addr
  312. ;
  313.  
  314.  
  315. : :LOC
  316.     local? 1 = IF  msg# 96  THEN    \ warning  - no locals defined
  317.     ?loc
  318.     ' drop                            \ gobble word name
  319.  
  320.     CDP -> const_data_start            \ the following is like :f (see qpCond)
  321.     $ BE020000  code,                \ marks this as the :loc position
  322.                                     \  (just for disassembly)
  323.  
  324.     false -> method?
  325.     false -> local?                    \ so entry sequence gets compiled
  326.     true ppc_entry                    \ handle ppc proc entry.  We're handling
  327.                                     \  local sections by calling FORWARD,
  328.                                     \  so we need to tell ppc_entry this
  329.                                     \  is a forward defn so the parms get
  330.                                     \  handled properly.
  331.     fwd_gpr_rtn_cnt  -> gpr_rtn_cnt
  332.     fwd_fpr_rtn_cnt  -> fpr_rtn_cnt
  333.     drop 304                        \ security marker for :loc
  334.     curr-def
  335.       loc_addr -> curr-def
  336.       PLentry
  337.     -> curr-def
  338.     tempObj_block_size IF  initTemps  THEN
  339. ;        immediate
  340.  
  341. : ;LOC
  342.     304 ?defn
  343.     false -> leaf?            \ let's just reduce the bug possibilities!
  344.     loc_addr 2-  (;)
  345.     loc_addr curr-def  resolve_unconditional_branch
  346.                             \ resolve the forward branch from LOCAL
  347.     false -> localSect?
  348. ;            immediate
  349.  
  350.  
  351. \            ============================================
  352.  
  353. \ EVALUATE was already loaded in pArgs, along with the value compinline?.
  354.  
  355. : (COMPINL)        \ ( xt -- )
  356.  
  357.     true -> compinline?
  358.     2+ count  evaluate
  359.     false -> compinline?  ;
  360.  
  361. ' (compinl) -> compinline
  362.  
  363.  
  364. : [IF]  { flag \ addr len level done? -- }
  365.  
  366.     flag  ?EXIT
  367.     false -> done?  1 -> level
  368.  
  369.     BEGIN
  370.         Mword count  -> len  -> addr
  371.                 addr len  " [THEN]" s=  IF  1 --> level
  372.         ELSE    addr len  " [ELSE]" s=    IF  level 1 =
  373.                                             IF  true -> done?  THEN
  374.         ELSE    addr len  " [IF]"   s=  IF  1 ++> level
  375.         THEN THEN THEN
  376.  
  377.         level  NIF  true -> done?  THEN
  378.         done?
  379.     UNTIL
  380. ;                immediate
  381.  
  382.  
  383. : [ELSE]  { \ addr len level done? -- }
  384.     false -> done?  1 -> level
  385.     BEGIN
  386.         Mword count  -> len  -> addr
  387.                 addr len    " [THEN]" s=  IF  1 --> level
  388.         ELSE    addr len    " [IF]"   s=  IF  1 ++> level
  389.         THEN THEN
  390.  
  391.         level  NIF  true -> done?  THEN
  392.         done?
  393.     UNTIL
  394. ;                immediate
  395.  
  396.  
  397. : [THEN]  ;        immediate
  398.  
  399.  
  400.  
  401. (*    INSTEAD ( c-old c-new -- )  may be used just after a SCON is defined.
  402.     Within the SCON, it replaces any occurrences of c-old with c-new.  This 
  403.     operation is useful for creating SCONs containing special characters
  404.     such as tab.
  405.     This logically should come after SCON in zBase, but it needs locals
  406.     so we'll put it here.
  407. *)
  408.  
  409. : INSTEAD  { c-old c-new -- }
  410.     latest name> ex-gen  bounds        \ SCONs use DOES> so require EX-GEN
  411.     DO   i c@ c-old = IF  c-new i c!  THEN
  412.     LOOP  ;
  413.  
  414.  
  415. \                    =============================
  416. \                            ASSERTIONS
  417. \                    =============================
  418.  
  419. (*    Assertions allow you, during development, to ensure that
  420.     things are the way they're supposed to be at key places.
  421.     
  422.     Usage:
  423.     ASSERT{ <something that evaluates to a flag> }
  424.     
  425.     If ASSERTIONS? is true, this will give error 216 ("assertion failed")
  426.     if the evaluated flag is false.  If ASSERTIONS? is false, nothing
  427.     will happen - the code between ASSERT{ and } isn't executed.
  428.  
  429.     ASSERTIONS? can be defined and redefined however and whenever you
  430.     like, as long as it returns a flag - ASSERT{ tests it via EVALUATE,
  431.     so the latest definition will always be the one that gets looked at.
  432.     If you have ASSERTIONS? defined as a constant with value false, no 
  433.     code will even be compiled for the assertion test - you can use this
  434.     for code that you know works.
  435.     
  436.     The initial version of ASSERTIONS? is in the file Setup.
  437. *)
  438.  
  439. : }ASSERT
  440.     134 ?pairs
  441.     ['] } >body !                    \ restore old action for "}"
  442.  
  443.     " NIF 216 die THEN THEN"  evaluate        \ assertion failed!
  444. ;        immediate
  445.  
  446.  
  447. : ASSERT{
  448.     ?comp
  449.     " assertions? if" evaluate
  450.     
  451.     ['] } >body @                \ save old action for "}"
  452.     ['] }assert  -> }            \ "}" will now be same as }assert
  453.     134
  454. ;        immediate
  455.